package cn.ticsmyc.tools.multiThread.producerConsumer;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;

/**
 * 基于Semaphore流控的channel实现
 *
 * @author Ticsmyc
 * @date 2021-06-02 16:55
 */
public class SemaphoreBasedChannel<P> implements Channel<P> {

    private Semaphore semaphore;

    private BlockingQueue<P> blockingQueue;

    public SemaphoreBasedChannel(int limit) {
        this.blockingQueue = new LinkedBlockingQueue<>();
        this.semaphore = new Semaphore(limit);
    }

    @Override
    public P take() throws InterruptedException {
        return blockingQueue.take();
    }

    @Override
    public void put(P product) throws InterruptedException {
        semaphore.acquire();
        try {
            blockingQueue.put(product);
        } finally {
            semaphore.release();
        }

    }
}
